/*
 * @Descripttion: 调试节点工具,可在运行时查看节点位置,描点信息
 * @Author: jindekun
 * @Date: 2022-03-14 09:58:20
 */

import * as cc from "cc";
import { GlobalConfig } from "../../GlobalConfig";

export default class DebugUtils {
    static _debugTag: string = "1486940"

    private static _initNode(node: cc.Node, lineWidth: number = 2, strokeColor: cc.Color = cc.Color.RED, fillColor = cc.color(0xff, 0, 0, 50)){        
        let chNode = node.getChildByName(DebugUtils._debugTag)
        //单独加一个调试节点,用于显示一些额外信息.
        if (chNode == null) {
            chNode = new cc.Node(DebugUtils._debugTag)
            chNode.addComponent(cc.UITransform);
            chNode.setParent(node);
            chNode.layer = node.layer;
            chNode.setSiblingIndex(10000);
        }

        let chTrans = chNode.getComponent(cc.UITransform);
        let nodeTrans = node.getComponent(cc.UITransform);
        chTrans.width = nodeTrans.width
        chTrans.height = nodeTrans.height
        chTrans.setAnchorPoint(nodeTrans.anchorPoint)
        chNode.setPosition(0, 0)

        let g = chNode.getComponent(cc.Graphics)
        if (g == null) {
            g = chNode.addComponent(cc.Graphics)
        }

        g.clear();
        g.lineWidth = lineWidth;
        g.strokeColor = strokeColor
        g.fillColor = fillColor

        return {
            node:chNode,
            g:g,
        };
    }


    /**
     * 绘制节点的大小,锚点信息
     * @param node 绘制调试节点的父节点
     * @param strokeColor 边框颜色
     * @param fill 是否填充颜色
     * @param fillColor 填充色
     * @returns 
     */
    static showBound(node: cc.Node, lineWidth: number = 2, strokeColor: cc.Color = cc.Color.RED, fill: boolean = true, fillColor = cc.color(0xff, 0, 0, 50)) {
        if (!GlobalConfig.debug) return
        
        let chNode = this._initNode(node,lineWidth,strokeColor,fillColor);
        let g = chNode.g;
        let nodeTrans = node.getComponent(cc.UITransform);
        let chTrans = chNode.node.getComponent(cc.UITransform);

        let rect = nodeTrans.getBoundingBox();

        let x = - rect.width * nodeTrans.anchorX
        let y = - rect.height * nodeTrans.anchorY
        if (fill) {
            g.fillRect(x, y, rect.width, rect.height)
            g.fill()
        }
        g.circle(chTrans.anchorX * chTrans.width, chTrans.anchorY * chTrans.height, 5)
        g.rect(x, y, rect.width, rect.height)
        g.stroke()

    }
    /**
     * 绘制一个世界坐标框
     * @param node 绘制调试节点的父节点
     * @param worldRect 世界坐标组成的rect
     * @param strokeColor 边框颜色
     * @param fill 是否填充颜色
     * @param fillColor 填充色
     * @returns 
     */
    static showRect(node: cc.Node, lineWidth: number = 2, worldRect: cc.Rect, strokeColor: cc.Color = cc.Color.RED, fill: boolean = true, fillColor = cc.color(0xff, 0, 0, 50)) {
        if (!GlobalConfig.debug) return
        let chNode = this._initNode(node,lineWidth,strokeColor,fillColor);
        let g = chNode.g;
        let nodeTrans = node.getComponent(cc.UITransform);
        let rect = worldRect;
        let pos = nodeTrans.convertToNodeSpaceAR(cc.v3(worldRect.x, worldRect.y));
        let center = nodeTrans.convertToNodeSpaceAR(cc.v3(worldRect.center.x,worldRect.center.y));

        if (fill) {
            g.fillRect(pos.x, pos.y, rect.width, rect.height)
            g.fill()
        }
        g.circle(center.x, center.y, 5)
        g.rect(pos.x, pos.y, rect.width, rect.height)
        g.stroke()
    }
    
    /**
     * 绘制一个多边形
     * @param node 绘制调试节点的父节点
     * @param arrWorldPos 多边形的顶点世界坐标数组
     * @param strokeColor 边框颜色
     * @param fill 是否填充颜色
     * @param fillColor 填充色
     * @returns 
     */
    static showPolygon(node: cc.Node, lineWidth: number = 2, arrWorldPos: cc.Vec2[], strokeColor: cc.Color = cc.Color.RED, fill: boolean = true, fillColor = cc.color(0xff, 0, 0, 50)) {
        if (!GlobalConfig.debug) return

        let chNode = this._initNode(node,lineWidth,strokeColor,fillColor);
        let g = chNode.g;
        let nodeTrans = node.getComponent(cc.UITransform);
                
        let firstPos = nodeTrans.convertToNodeSpaceAR(cc.v3(arrWorldPos[0].x,arrWorldPos[0].y));
        g.moveTo(firstPos.x,firstPos.y);
        for (let i = 1; i < arrWorldPos.length; i++) {
            const pos = nodeTrans.convertToNodeSpaceAR(cc.v3(arrWorldPos[i].x,arrWorldPos[i].y));
            g.lineTo(pos.x,pos.y);
        }
        g.moveTo(firstPos.x,firstPos.y);        
        if (fill) {
            g.fill();
        }
        g.stroke();
    }

    static clearBound(node: cc.Node) {
        if (!GlobalConfig.debug) return
        let chNode = node.getChildByName(DebugUtils._debugTag);
        if (chNode != null) {
            chNode.destroy();
        }
    }
}